﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Luna.Framework.Manifest;
using System.Windows.Forms;
using System.Drawing;

namespace Luna.Framework.Impl {

	public enum MenuItemType {
		Button, Label, Separator, DropDown
	}

	public class MenuStripRenderer: IMenuRenderer {

		private IActionManager actionVault;

		public object renderMenu(object menuControl, IManifest manifest, IAppContext context) {
			MenuStrip menu = menuControl is MenuStrip ? menuControl as MenuStrip : new MenuStrip();
			actionVault = context.getService<IActionManager>();

			if (manifest.hasChild()) {
				IList<IManifest> children = manifest.getChildren();
				foreach (IManifest child in children) {
					if (child.Name.Equals("item"))
						menu.Items.Add(createMenuItem(child, context, menu.Items));
				}
			}
			return menu;
		}

		public virtual ToolStripItem createMenuItem(IManifest item, IAppContext context, ToolStripItemCollection items) {
			ToolStripItem result = null;
			MenuItemType type = item.getProperty<MenuItemType>("type", MenuItemType.Button);
			string name = item.getProperty<string>("name", "");
			switch (type) {
				case MenuItemType.Button:
					ToolStripMenuItem mItem = (ToolStripMenuItem) items.Find(name, false).FirstOrDefault();
					if (mItem == null) {
						mItem = new ToolStripMenuItem();
						if (actionVault != null) {
							string actName = item.getProperty<string>("action");
							IActionable act = actionVault.getAction(actName);
							if (act != null) {
								mItem.Name = act.Name;
								mItem.Click += (o, e) => act.execute(o, new ActionExecutionArgs() {
									Action = act,
									Args = e,
									Data = item,
									Context = context
								});
								if (act is IVisualActionable) {
									IVisualActionable vact = (IVisualActionable)act;
									mItem.Text = vact.Text;
									mItem.Image = vact.Image;
									mItem.Enabled = vact.Enabled;

									vact.TextChanged += (o, e) => mItem.Text = (o as IVisualActionable).Text;
									vact.ImageChanged += (o, e) => mItem.Image = (o as IVisualActionable).Image;
									vact.EnableChanged += (o, e) => mItem.Enabled = (o as IVisualActionable).Enabled;
								}
							}
						}
						// decorate the menu item
						mItem.Image = item.getProperty<Image>("image", mItem.Image);
					}
					// create child item
					if (item.hasChild())
						foreach (IManifest child in item.getChildren())
							if ("item".Equals(child.Name)) {
								ToolStripItem childItem = createMenuItem(child, context, mItem.DropDownItems);
								mItem.DropDownItems.Add(childItem);
							}

					// create  handler for this item, if any
					result = (ToolStripItem)mItem;
					break;
				case MenuItemType.Separator:
					result = new ToolStripSeparator();
					break;
				default:
					break;
			}
			if (result != null) {
				result.Name = item.getProperty<string>("name", result.Name);
				result.Text = item.getProperty<string>("text", result.Name);
				result.ToolTipText = item.getProperty<string>("tooltip", result.Text);
			}
			return result;
		}
	}
}
